﻿using System;
using K9Nano.Share.Extensions;
using K9Nano.Share.Reflection;

namespace K9Nano.Events.Entity
{
    public class EntityChange
    {
        public EEntityChangeType EntityChangeType { get; }

        public object Entity { get; }

        private object _id;

        public object Id => _id ??= Entity.GetProperty("Id");

        public EntityChange(EEntityChangeType entityChangeType, object entity, object id, bool enableEvent, bool enableCache)
        {
            EntityChangeType = entityChangeType;
            Entity = entity;
            _id = id;

            var type = EntityType;
            CacheDisabled = !enableCache || type.HasCustomAttribute<CacheDisabledAttribute>(false);
            EventDisabled = !enableEvent || type.HasCustomAttribute<EventDisabledAttribute>(false);
        }

        public readonly bool EventDisabled;

        public readonly bool CacheDisabled;

        public Type EntityType => Entity.GetType();

        public Type[] EntityEventDataTypes
        {
            get
            {
                var result = new Type[2];

                switch (EntityChangeType)
                {
                    case EEntityChangeType.Created:
                        result[0] = typeof(EntityCreatedEventData<>).MakeGenericType(EntityType);
                        break;
                    case EEntityChangeType.Updated:
                        result[0] = typeof(EntityUpdatedEventData<>).MakeGenericType(EntityType);
                        break;
                    case EEntityChangeType.Deleted:
                        result[0] = typeof(EntityDeletedEventData<>).MakeGenericType(EntityType);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }

                result[1] = typeof(EntityChangedEventData<>).MakeGenericType(EntityType);

                return result;
            }
        }
    }
}